﻿#define  _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>

//strncpy的实现
#include<string.h>
#include<assert.h>
char* my_strncpy(char* des, const char* src,int sz)
{
	assert(des && src);
	char* ret = des;

	while (sz--)
	{
		if (*src != '\0')
		{
			*des = *src;
			des++;
			src++;
		}
		else
		{
			*des = '\0';
			des++;
		}
	}

	return des;
}

char* my_strncat(char* des, const char* src, int sz)
{
	assert(des && src);
	char* ret = des;

	while (*des)
	{
		des++;
	}
	
	while (sz--)
	{
		if (*src == '\0')
		{
			*des = *src;
			return ret;
		}
		*des = *src;
		des++;
		src++;
	}
	//追加
	*des = '\0';

	return ret;
}
int main0()
{
	char arr1[] = "world";
	char arr2[30] = "Hello ";
	strncpy(arr2, arr1, 2);
	printf("%s",arr2);
	return 0;
}


//memcpy 内存拷贝函数
void* my_memcpy(void* des, void* src, size_t num)
{
	int i = 0;
	void* ret = des;
	assert(des && src);
	while (num--)
	{
		*((char*)des + i) = *((char*)src + i);
		i++;
	}
	return ret;
}

void* my_memmove(void* des, void* src, size_t num)
{
	int i = 0;
	void* ret = des;
	assert(des && src);
	if (des < src)
	{
		//从前向后
		while (num--)
		{
			*((char*)des + i) = *((char*)src + i);
			i++;
		}
	}
	else
	{
		//从后向前
		while(num--)
		{
			*((char*)des + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main1()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[30] = { 0 };
	my_memmove(arr1, arr1+2, 20); //3 4 5 6 7 6 7 8 9 10
	
	for (int i = 0; i < 10; i++)
	{
		printf("%d ",arr1[i]);
	}
	return 0;
}


int main2()
{
	unsigned char a = 200; //1100 1000
	unsigned char b = 100; //0110 0100
	unsigned char c = 0;   //0000 0000
	c = a + b;
	printf( "%d %d", a + b, c); //300 44
	return 0;
}

int main3()
{
	char a[1000] = { 0 };
	int i = 0;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));

	//-127
	//1111 1111
	//128
	//1000 0000
	//-128
	//1000 0000
	//-128 -1
	//0111 1111 127

	return 0;
}

//判断大小端
int check_sys()
{
	int i = 1; //0x00 00 00 01

	char* p = (char*)&i;

	return *p;

}
int main4()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

#include <stdio.h>
unsigned char i = 0;  //取值范围0~255， 255 + 1 = 0
int main5()
{
	for (i = 0; i <= 255; i++)
	{
		printf("hello world\n");  //死循环
	}
	return 0;
}


#include <stdio.h>
int main6()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i); //9 8 7 6 5 4 3 2 1 0 
	}
	return 0;
}

#include <stdio.h>
//x86环境下 小端字节序
int main7()
{   //                                                                                              低地址                                      高地址               
	int a[4] = { 1, 2, 3, 4 };  //数组数据从低地址向高地址进行排序，所以排在内存中如果是小端字节序的话，那么就是01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
	int* ptr1 = (int*)(&a + 1);  //ptr1取出数组的地址并且向后加1跳过整个数组，
	int* ptr2 = (int*)((int)a + 1); //a数组名代表首元素的地址，首元素的地址转为整型（就是把地址看成整数，整数+1就是加1），再去转换成int*类型，表示跳过了一个字节
	printf("%x,%x", ptr1[-1], *ptr2);
	//            *（ptr1 - 1）
	return 0;
}


//任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式：
//V = (−1)^s ∗ M ∗ 2^E
//对于32位的浮点数，最⾼的1位存储符号位S，接着的8位存储指数E，剩下的23位存储有效数字M
//对于64位的浮点数，最⾼的1位存储符号位S，接着的11位存储指数E，剩下的52位存储有效数字M
//如果小数点后的位太多，就可能导致浮点数在内存中无法精确的保存
#include <stdio.h>
int main()
{
	int n = 9; //00000000 00000000 00000000 00001001  --> 0.000000 * 2^9 = 0.000000
	float* pFloat = (float*)&n;
	printf("n的值为：%d\n", n);
	printf("*pFloat的值为：%f\n", *pFloat);//0.000000
	*pFloat = 9.0;  //9.0 = s = 0,M = 1.001,E = 130. 0100 0001 0010 0000 0000 0000 0000 0000
	printf("num的值为：%d\n", n);
	printf("*pFloat的值为：%f\n", *pFloat);
	return 0;
}